<template>
  <transition name="notification">
    <div class="popup-layout" :style="{ 'z-index': zIndex }" v-if="value">
      <div class="layout-content" :style="{ width: width + 'px' }">
        <div class="layout-head">
          <div class="layout-title">{{ title }}</div>
          <div class="layout-close" @click="emitHandle('close')"></div>
        </div>
        <div class="layout-slot" ref="layoutSlot">
          <TrForm
            ref="trEdit"
            :formData="formData"
            v-model="dataObj"
            :labelWidth="labelWidth"
            :list="list"
            :contentWidth="width"
            :relationList="relationList"
            @select-change="selectChange"
            @radio-change="changeRadioHandle"
            @load-label="changeLoadlabel"
            @input-change="inputChange"
            @clear="clearHandle"
          >
            <template
              v-for="it in list.filter((k) => k.type == 'slot')"
              #[it.slotName]="{ item }"
            >
              <slot :name="it.slotName" v-bind="item"></slot>
            </template>
          </TrForm>
        </div>
        <div class="footer-list" :class="{ 'has-scroll': checkIsScroll }">
          <div
            class="footer-btn"
            :class="item.color"
            v-for="(item, index) in footerList"
            :key="index"
            @click="emitHandle(item.option)"
          >
            {{ item.label }}
          </div>
        </div>
      </div>
    </div>
  </transition>
</template>

<script>
import { cloneDeep } from "lodash-es";
import TrForm from "./Tr-form.vue";
export default {
  name: "TrFormPopup",
  components: {
    TrForm,
  },
  props: {
    value: {
      type: Boolean,
      default: false,
    },
    zIndex: {
      type: Number,
      default: 1001,
    },
    width: {
      type: Number,
      default: 960,
    },
    labelWidth: {
      type: Number,
      default: 80,
    },
    title: {
      type: String,
      default: "新增",
    },
    formData: {
      type: Object,
      default: () => {},
    },
    list: {
      type: Array,
      default: () => [],
    },
    slotList: {
      type: Array,
      default: () => [],
    },
    footerList: {
      type: Array,
      default: () => [
        {
          label: "取消",
          option: "close",
          color: "white",
        },
        {
          label: "保存",
          option: "confrim",
          color: "blue",
        },
      ],
    },
    valueObj: {
      type: [Object],
    },
    relationList: {
      type: Array,
      default: () => [],
    },
  },
  watch: {
    value: {
      handler(val) {
        if (!val) return;
        // this.$nextTick(() => {
        //   const ele = document.getElementsByClassName("layout-slot")[0];
        //   this.checkIsScroll = ele.scrollHeight > ele.clientHeight;
        // });
        this.$nextTick(() => {
          this.observeWithResizeObserver();
        });
      },
    },
    dataObj: {
      handler(newValue) {
        this.$emit("update:valueObj", Object.assign(this.valueObj, newValue));
      },
      deep: true,
    },
  },
  data: () => ({
    dataObj: {},
    checkIsScroll: false,
    initValue: {},
  }),
  methods: {
    clearHandle(val) {
      this.$emit("clear", val);
    },
    observeWithResizeObserver() {
      const element = this.$refs.layoutSlot;
      const observer = new ResizeObserver((entries) => {
        entries.forEach((entry) => {
          this.checkIsScroll =
            entry.target.scrollHeight > Math.ceil(entry.contentRect.height);
        });
      });

      observer.observe(element);
      this.$once("hook:beforeDestroy", () => {
        observer.disconnect();
      });
    },
    changeLoadlabel(val) {
      this.$emit("load-label", val);
    },
    changeRadioHandle(val) {
      this.$emit("radio-change", val);
    },
    emitHandle(type) {
      if (type == "close") {
        this.$emit("update:valueObj", this.initValue);
        this.$emit(type, type);
        return;
      }
      let flag = this.$refs.trEdit.validateHandle();
      this.$nextTick(() => {
        if (flag) return this.$emit(type, type);
      });
    },
    selectChange(val) {
      this.$emit("select-change", val);
    },
    outReset(id, val) {
      this.$refs.trEdit.resetCloneList(id, val);
    },
    inputChange(val) {
      this.$emit("input-change", val);
    },
  },
  mounted() {
    this.dataObj = cloneDeep(this.valueObj);
    this.initValue = cloneDeep(this.initValue);
  },
};
</script>

<style lang="scss" scoped>
.popup-layout {
  position: fixed;
  width: 100vw;
  height: 100vh;
  background: rgba(#000, 0.4);
  top: 0;
  left: 0;
  display: flex;
  align-items: center;
  justify-content: center;
  transition: all 0.5s;
  .layout-content {
    padding: 24px;
    display: flex;
    flex-direction: column;
    background: #fff;
    border-radius: 8px;
    box-shadow: 0px 2px 4px -1px rgba(0, 0, 0, 0.12),
      0px 4px 5px 0px rgba(0, 0, 0, 0.08), 0px 1px 10px 0px rgba(0, 0, 0, 0.05);
    .layout-head {
      display: flex;
      justify-content: space-between;
      align-items: center;
      margin-bottom: 16px;
      .layout-title {
        color: rgba(#000, 0.9);
        font-weight: 600;
        line-height: 24px;
      }
      .layout-close {
        width: 20px;
        height: 20px;
        background-image: url("~@/assets/icons/close_2.png");
        background-size: contain;
        cursor: pointer;
      }
    }
    .layout-slot {
      flex: 1;
      max-height: 570px;
      overflow-y: auto;
      overflow-x: hidden;
    }
    .footer-list {
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: flex-end;
      .footer-btn {
        height: 32px;
        border: 1px solid #0087d6;
        display: flex;
        align-items: center;
        justify-content: center;
        margin-left: 16px;
        padding: 0 15px;
        border-radius: 3px;
        font-size: 14px;
        transition: all 0.3s;
        cursor: pointer;
        &.white {
          background: #fff;
          color: #0087d6;
          &:hover {
            color: #4e52da;
            border: 1px solid #4e52da;
          }
        }
        &.blue {
          background: #0087d6;
          color: #fff;
          &:hover {
            background: #4e52da;
            border: 1px solid #4e52da;
          }
        }
      }
      &.has-scroll {
        padding-top: 24px;
        border-top: 1px solid #e7e7e7;
      }
    }
  }
}
</style>
